
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include "../luaParametersSweep.h"
#include "../global.h"
#include <iostream>
#include <boost/filesystem.hpp>
#include <log/log.h>
#include <appendix/phy_constants.h>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <thread>
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <tuple>


namespace lua{
	luaParametersSweep::luaParametersSweep()
	:m_bNeedEvaluate(false),m_bValid(true),m_bSynatexError(false)
	{
	}

	bool luaParametersSweep::value( const std::string& key, std::vector<double>& val)
	{
		if(m_varibles.find(key)!=m_varibles.end()){
			val = m_varibles[key];
			return true;
		}
		return false;
	}
	bool luaParametersSweep::set_value( const std::string& key, const std::vector<double>& val)
	{
		m_varibles[key] = val;
		return true;
	}

	void luaParametersSweep::setState(std::shared_ptr<luaState> state)
	{
		m_state = state;
		initState();
	}

	bool luaParametersSweep::initState()
	{
		 {
			 std::scoped_lock lk( *( m_state->mutex() ) );
			 sol::state_view lua( m_state->state() );
			 m_module = lua.create_named_table("ParametersSweep");
//			 m_module = LuaHelp::open_luaParameters( sol::this_state(_state->state()) );
		 }
	}

	bool grids(std::vector< std::vector<double> >& sheet, int ncols, int idx, std::vector<double>& vals )
	{
		//
		if(!vals.size()) return false;

		if( !sheet.size() ){
			for(int ii=0; ii < vals.size(); ii++ ){
				std::vector<double> data(ncols);
				data[idx] = vals[ii];
				sheet.push_back(data);
			}
			return true;
		}

		int nold = sheet.size();

		for( int jj=0; jj < nold; jj++ ){
			sheet[jj][idx] = vals[0];
		}

		for( int ii=1; ii < vals.size(); ii ++){
			for( int jj=0; jj < nold; jj++ ){
				std::vector<double> data = sheet[jj];
				data[idx] = vals[ii];
				sheet.push_back(data);
			}
		}
		return true;
	}
	bool luaParametersSweep::init_data_sheet()
	{
		if(!m_varibles.size()) return false;

		int nvals = m_varibles.size();
		int nlists = 1;
		for(auto& v:m_varibles){
			nlists *= v.second.size();
		}

		m_parasSheet.clear();
		m_parasSheet.reserve(nlists);

		int ncols_idx = 0;
		for(auto& v:m_varibles){
			if(! grids(m_parasSheet,nvals,ncols_idx++,v.second) )
				return false;
		}

		std::ostringstream out;
		out << std::endl;
		for(auto& v:m_varibles){
			out << v.first << "\t";
		}
		out << std::endl;
		for(auto&& data:m_parasSheet){

			for(auto&& d:data){
				out << d << "\t";
			}
			out << std::endl;
		}
		logs::info_log(boost::format("%1%") % out.str());

		return true;
	}

};


